home *** CD-ROM | disk | FTP | other *** search
/ Merciful 4 / Merciful - Disc 4.iso / software / p / psychotoads.dms / psychotoads.adf / a1113 < prev    next >
Text File  |  1989-03-31  |  60KB  |  1,565 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.                          11: HARDWARE SPRITES                              145
  10.                       --------------------------
  11. One of the biggest attractions of the Commodore Amiga is its ability to
  12. produce high quality games which rivial those found on genuine arcade
  13. machines. This can be amply demonstrated by terrific programs such as
  14. Battle Squadron and Eliminator.
  15.  
  16.   Now, for the first time, all these amazing features are at your
  17. fingertips! AMOS Basic provides you with complete control over the
  18. Amiga's hardware and software sprites. These sprites can be
  19. effortlessly manoeuvred with the built-in AMAL animation language, so
  20. you don't have to be a machine code wizard in order to create your own
  21. stunning arcade games.
  22.  
  23.   Hardware sprites are searate images which can be automatically
  24. overlayed on the Amiga's screen. The classic example of a hardware
  25. sprite is the mouse pointer. This is completely independent of the
  26. screen, and works equally well in all the Amiga's graphics modes.
  27.  
  28.   Since sprites don't interfere with the screen background, they are
  29. perfect for the moving objects required by an arcade game. Not only are
  30. they blindingly fast, but they also take up very little memory. So when
  31. you're writing an arcade game, hardware sprites should always be at the
  32. top of your list.
  33.  
  34.   Each sprite is 16 pixews wise and up to 255 pixels high. The Amiga's
  35. hardware supports a maximum of eight three-colour sprites or four
  36. fifteen-colour sprites. Colour number zero is transparent - that's the
  37. reason for the odd colour ranges.
  38.  
  39.   At first glance, these features don't seem particulary impressive.
  40. But there are a couple of useful tricks which can increase both the
  41. numbers and sizes of these sprites beyond recognition.
  42.  
  43.   One solution is to take each hardware sprite and split it into a
  44. number of horizontal segments. These segments can be independently
  45. positioned, allowing you to apparently display dozens of sprites on the
  46. screen at once. Similarly, the width restriction can be exceeded by
  47. building an object out of several individual sprites. Using this
  48. technique it's easy to generate objects up to 128 pixels wide.
  49.  
  50.   Until recently the only way to exploit these techniques was to delve
  51. into the mysterious wolrd of 68000 assembler language. So you'll be
  52. delighted to discover that AMOS Basic manages the entire process
  53. automatically! Once you've designed your sprites with the AMOS sprite
  54. editor, you can effortlessly manipulate them with just a single Basic
  55. instruction.
  56.  
  57.  
  58. The sprite commands
  59. ===================
  60. Remember to have a sprite bank loaded into memory when trying out the
  61. various commands in this chapter. We advise you use the file
  62. SPRITES.ABK from the AMOS data disc.
  63.  
  64.  
  65.  
  66.            SPRITE (display a hardware sprite on the screen)
  67.  
  68. SPRITE n,x,y,i
  69.  
  70. The SPRITE command displays a hardware sprite on the screen at
  71. coordinates x,y using image number i.
  72.  
  73.   n is the identification number of the sprite and can range from 0 to
  74. 63. Each sprite can be associated with a separate image from the sprite
  75. bank, so the same image can be used for several sprites.
  76.  
  77.   x and y hold the position of the sprite using special hardware           146
  78. coordinates. All measurements are taken from the *hot spot* of your
  79. images. This serves as a sort of 'handle' on the sprite and is used as
  80. a reference point for the coordinates. Normally the hot spot is set to
  81. the top left hand corner of an image. However it can be changed within
  82. your program using the HOT SPOT command.
  83.  
  84.   Hardware coordinates are independent of the screen mode and
  85. effectively start from (-129,-45) on the default screen. AMOS provides
  86. you with several built-in functions for conversions between hardware
  87. coordinates and the easier to use screen coordinates. See the X HARD,
  88. Y HARD, X SCREEN and Y SCREEN functions for more details.
  89.  
  90.   i is the number of a particular image stored in the sprite bank. This
  91. bank can be created using the AMOS sprite editor, and is automatically
  92. saved along with your Basic program. It can also be loaded directly
  93. with the LOAD instruction. In addition you can use the GET SPRITE
  94. command to grab an image straight off the current screen.
  95.  
  96.   Any of these parameters x,y and i may be optionally omitted, but the
  97. appropriate commas must be included. For example:
  98.  
  99.         Load "AMOS_DATA:Sprites/Octopus.abk"
  100.         Sprite 8,200,100,1
  101.         Sprite 8,,150,1
  102.         Sprite 8,300,,
  103.  
  104. For a demonstration of sprites in action, load EXAMPLE 11.1 from the
  105. MANUAL folder on the AMOS data disc.
  106.  
  107.  
  108. Computed sprites
  109. ================
  110. Although the Amiga only provides you with eight actual sprites, it's
  111. possible to use them to display up to 64 different objects on the
  112. screen at once. These objects are known as -computed sprites- and are
  113. managed antirely by AMOS Basic. Computed sprites can be assigned by
  114. calling the SPRITE command with a number greater than 7. For example,
  115.  
  116.         Load "AMOS_DATA:Sprites/Octopus.abk"
  117.         Sprite 8,200,100,1
  118.  
  119. The size of a computed sprite is taken directly from the image data,
  120. and can vary between 16 and 128 pixels wide, and from 1 to 255 pixels
  121. high.
  122.  
  123.   Before you can make full use of these sprites you need to understand
  124. some of the principles behind them. Each hardware sprite consists of a
  125. thin narrow strip 16 pixels wide and 256 pixels deep. Depending on the
  126. number of colours, you can have either eight or four of these strips on
  127. the screen at a time.
  128.  
  129.   It should be obvious that most of the area inside these sprites is       147
  130. effectively wasted. That's because few programs need sprites which are
  131. taller than about 40 or 64 pixels. However there is a simple trick
  132. which enables us to borrow this space to generate dozens of extra
  133. objects on the screen. Look at the picture AMOS1.PIC (included in this
  134. manual file packet) which contains the letters A,M,O and S.
  135.  
  136.            < picture   AMOS1.PIC >
  137.  
  138. This sprite can be split into four horizontal segments each enclosing a
  139. single letter. The Amiga's hardware allows each section to be freely
  140. positioned anywhere on the current line, making a total of four
  141. computed sprites. Here's a diagram which illustrates this process.
  142.  
  143.            < picture   AMOS2.PIC >                                         148
  144.  
  145. As you can see, a computed sprite is really just a small part of a
  146. hardware sprite displayed at a different horizontal screen position.
  147. Notice the line between each object. This is an unavoidable side effect
  148. of the repositioning process, and is generated by the Amiga's hardware.
  149.  
  150.   Due to the way computed sprites are produced, there are a couple of
  151. restrictions to their use. Firstly, you can't have more than 8 computed
  152. sprites on a single line. In practice the system is complicated by the
  153. need to produce sprites which are larger than the 16 pixel maximum.
  154. AMOS generates these objects by automatically positioning several
  155. computed sprites side by side. This can be seen from the diagram below:
  156.  
  157.            < picture   AMOS3.PIC >
  158.  
  159. The maximum of eight hardware sprites therefore imposes a strict limit
  160. to the number of such objects you can display on a horizontal line. The
  161. total width of the objects must not exceed:
  162.  
  163.         16*8=128 pixels for three-colour sprites                           149
  164.         16*4=64  pixels for fifteen-colour sprites
  165.  
  166. If you attempt to ignore limitation, you won't get an error message,
  167. but your computer sprite will not be displayed on the screen. So it's
  168. vital to ensure that the above restriction is never broken. This can be
  169. achieved using the following procedure:
  170.  
  171.   Add together the widths of all your computed sprites, multiplying the
  172. dimensios of any fifteen-colour sprites by two. If the total is
  173. greater than 128, you'll need to space your sprites on the screen so
  174. that their combined width lies below this value. Take particular care
  175. if you are animating your sprites with AMAL as certain combinations
  176. will only come to light after you've experimented with the sequence for
  177. some time. These problems will be manifested by the random
  178. disappearance of one or more sprites on the screen.
  179.  
  180.   If the worst comes to the worst, you'll need to substitute some of
  181. your larger sprites with Blitter Objects. This will increase the
  182. overall size of your program significantly, but it should have a
  183. negligible effect on the final quality of your game.
  184.  
  185.   These restrictions are not confined to AMOS Basic of course. They
  186. apply equally well to all games on the Amiga, even if they're written
  187. entirely in machine code! So there's nothing stopping you from
  188. producing your own Xenon II clone using exactly the same tehcniques.
  189.  
  190.   Note that, normally, hardware sprite number zero is allocated to the
  191. mouse cursor. You can release this sprite with a simple call to the
  192. HIDE command. See EXAMPLE 11.2.
  193.  
  194.  
  195. Creating an individual hardware sprite
  196. ======================================
  197. The only real problem with computed sprites is that you never know
  198. precisely which hardware sprite is going to be used in a particular
  199. object. Normally the hardware sprites used in an object will change
  200. whenever the object is moved. Occasionally this can be inconvenient,
  201. especially when you are animating objects such as missiles which need
  202. to remain visible in a wide range of possible sprite combinations.
  203.  
  204.   In these circumstances it's useful to be able to allocate a hardware
  205. sprite directly. Individual hardware sprites can be assigned using the
  206. SPRITE instruction with an identification number between 0 and 7.
  207. Example:
  208.  
  209.         Sprite 1,100,100,2
  210.  
  211. This loads a hardware sprite number 1 with image number 2. N now
  212. corresponds to the number of a single hardware sprite, and can range
  213. between 0 and 7. If your image is larger than sixteen pixels wide, AMOS
  214. will automatically grab the required sprites in consecutive order
  215. starting from the sprite you have chosen. For example:
  216.  
  217.         Sprite 2,200,100,1
  218.  
  219. Supposing image number 1 contained a 32-bit image with three colours.
  220. This command would allocate hardware spries 2 and 3 to the image.
  221. Nothing would happen if you were now to attempt to display hardware
  222. sprite 3 with a command like SPRITE 3,150,100,1  because this sprite
  223. has already been used. You would only have access to sprites 0,1,4,5,6
  224. and 7, and the maximum numbers and sizes of your computed sprites would
  225. be reduced accordingly.
  226.  
  227.   Each 15-colour sprite is implemented using a pair of two three-colour    150
  228. sprites. However, it's not possible to combinea ny two sprites in this
  229. way. Only the combinations 0/1,2/3,4/5,6/7 are allowed. One side effect
  230. of this, is that you should always assign your hardware sprites using
  231. even sprite numbers. Otherwise, AMOS will start your sprite from the
  232. next group of two, effectively wasting the first sprite.
  233.  
  234.   Also note that if you try to create a large fifteen-colour sprite
  235. with this system, you could easily use up all the available sprites in
  236. a single object.
  237.  
  238.   WARNING! If you are writing a screen scrolling game, you may
  239. encounter problems using sprites in conjunction with the SCREEN OFFSET
  240. and SCREEN DISPLAY commands. These generate a DMA clash between the
  241. sprite system and the screen bit-maps, and can occasionally lead to
  242. unwanted screen effects.
  243.  
  244.   This problem is only relevant if you are using hardware sprites 6/7.
  245. When the screen is shifted to the left with SCREEN OFFSET, the amount
  246. of time for your sprite updates is reduced, as the screen DMA has
  247. priority over the sprite system. Unfortunately, there isn't enough
  248. processing time to draw sprites 6/7, and they will therefore be
  249. corrupted on your display.
  250.  
  251.   To clear up this problem, create sprites 6/7 as individual hardware
  252. sprites and position them off the screen using negative coordinates.
  253. This will stop AMOS Basic from using them in your computed sprites.
  254. Providing sprites 6/7 are never displayed on the screen during your
  255. scrolling operations, all will be well.
  256.  
  257.  
  258. The sprite palette
  259. ==================
  260. The colours required by a hardware sprite are stored in the colour
  261. registers 16 to 31. Providing your current screen mode doesn't make use
  262. of these registers, the sprite colours will be completely separate from
  263. your screen colours. Interestingly enough, this is also the case for
  264. the 4096-colour Ham mode. So there's nothing stopping you from
  265. producing some mind-blowing Ham games with this system!
  266.  
  267.   However you will encounter real problems when using 32 or 64 colour
  268. screen in conjunction with three colour sprites. This is because the
  269. colours used by these sprites are grouped together in the following
  270. way:
  271.            Hardware sprites  Colour registers
  272.            ----------------  ----------------
  273.                  0 / 1         17 / 18 / 19
  274.                  2 / 3         21 / 22 / 23
  275.                  4 / 5         25 / 26 / 27
  276.                  6 / 7         29 / 30 / 31
  277.  
  278.    Colour registers 16,20,24 and 28 are treated as transparent.
  279.  
  280. The difficulty arises due to the way AMOS generates computed sprites.
  281. The hardware sprites used to produce these objects vary during the
  282. course of a game, so it's vital to ensure that the three colours used
  283. by each individual sprite are set to exactly the same values, otherwise
  284. the colours of your computed sprites will change unpredictably. Here's
  285. a small AMOS procedure which will perform the entire process for you       151
  286. automatically.
  287.  
  288.         Procedure INIT_SPRITES
  289.           Get Sprite Palette
  290.           For S=0 To 3
  291.             For C=0 To 2
  292.               Colour S*4+C+17,Colour(C)
  293.             Next C
  294.           Next S
  295.         Endproc
  296.  
  297. The above restriction does not, of course, apply to fifteen-colour
  298. sprites. If you want to make the most of the Extra Half Bright or
  299. 32-colour modes, you may find it easier to avoid using four-colour
  300. sprites altogether.
  301.  
  302.  
  303.  
  304.                     GET SPRITE PALETTE (grab sprite
  305.                          colours into screen)
  306.  
  307. GET SPRITE PALETTE [mask]
  308.  
  309. This loads the entire colour palette used for your sprite images into
  310. the current screen. The optional "mask" allows you to load just a
  311. selection of the colours from the sprite palette. Each of the 32
  312. colours is represented by a single bit in the mask, numbered from right
  313. to left. The rightmost bit represents the status of colour zero, the
  314. next vit colour 1, and so on. To load a colour simply set the
  315. appropriate bit to 1. If, for instance, you wanted to copy just the
  316. first four colours, you would set the bit pattern to:
  317.  
  318.         Get Sprite Palette %0000000000001111
  319.  
  320. Identically, since bobs use the same sprite bank as sprites, this
  321. command can also be used to load the colours of a bob.
  322.  
  323.  
  324. Controlling sprites
  325. ===================
  326.  
  327.  
  328.                  SET SPRITE BUFFER (set height of the
  329.                            hardware sprites)
  330.  
  331. SET SPRITE BUFFER n
  332.  
  333. This sets the work area in which AMOS creates the images of the
  334. hardware sprits. Acceptable values for n range from 16 to 256. TO set
  335. the correct value for n, simply examine the sprites in the sprite
  336. editor and work out which is the largest sprite length wise. ANy sprite
  337. that is larger than "n" will simply be truncated at the appropriate cut
  338. off point.
  339.  
  340.   SET SPRITE BUFFER is supplied for your use so that you can claim back
  341. any redundant memory our game or application simply doesn't use.
  342.  
  343.   The amount of memory consumed by the sprite buffer can be calculated
  344. using the formula:
  345.  
  346.         Memory = N*4*8*3 = N*96
  347.  
  348.   So the minimum buffer size is 1536 bytes and the maximum is 24k.
  349. Note: This command erases all current sprite assignments and resets the
  350. mouse cursor to its original state.
  351.  
  352.  
  353.  
  354.                     SPRITE OFF (remove one or more                         152
  355.                        sprites from the screen)
  356. SPRITE OFF [n]
  357.  
  358. The SPRITE OFF command removes one or more sprites from the screen. All
  359. current sprite movements are aborted. In order to restart them, you'll
  360. need to completely reinitialize your movement pattern.
  361.  
  362. SPRITE OFF    Removes all the sprites from display
  363.  
  364. SPRITE OFF n  Only deactivates sprite number n
  365.  
  366. Note that your sprites are automatically deactivated whenever you call
  367. up the AMOS Basic editor. They will be automatically returned to their
  368. original positions the next time you enter direct mode.
  369.  
  370.  
  371.  
  372.                SPRITE UPDATE (control sprite movements)
  373.  
  374. SPRITE UPDATE [ON/OFF]
  375.  
  376. The SPRITE UPDATE command provides you with total control of the
  377. movements of your sprites. Normally, whenever you move a sprite, its
  378. position is updated automatically during the next vertical blank period
  379. (see WAIT VBL). But if you are moving a lot of sprites using the SPRITE
  380. command, the updates will occur before all the sprites have been moved.
  381. This may result in a noticeable jump in yur movement patterns. In these
  382. circumstances, you can turn off the automatic updating system with the
  383. SPRITE UPDATE OFF command.
  384.  
  385.   Once your sprites have been succesfully moved, you can then slide
  386. them smoothly into place with a call to SPRITE UPDATE. This will
  387. reposition any sprites which have moved since your last update.
  388.  
  389.  
  390.  
  391.                =X SPRITE (get x coordinate of a sprite)
  392.  
  393. x=X SPRITE(n)
  394.  
  395. Returns the current x coordinate of sprite n, measured the hardware
  396. system. This command allows you to quickly check whether a sprite has
  397. passed of the edge of the Amiga's screen.
  398.  
  399.  
  400.  
  401.                =Y SPRITE (get y coordinate of a sprite)                    153
  402.  
  403. y=Y SPRITE(n)
  404.  
  405. Y SPRITE returns a sprite's vertical position. As usual, n refers to
  406. the number of the sprite and can range from 0 to 63. Remember, all
  407. sprite positions are measured in hardware coordinates. See EXAMPLE 11.3
  408.  
  409.  
  410.  
  411.                GET SPRITE (load a section of the screen
  412.                          into the sprite bank)
  413.  
  414. GET SPRITE [s,] i,x1,y1 TO x2,y2
  415.  
  416. This instruction enables you to grab images directly off the screen and
  417. turn them into sprites. The coordinates x1,y1 and x2,y2 define a
  418. rectangular area to be captured into the sprite bank. Normally all
  419. images are taken from the current screen. However it's also possible to
  420. grab the image from a specific screen using the optional screen number
  421. "s".
  422.  
  423.   Note: There are no limitations to the region that may be grabbed in
  424. this way. Providing your coordinates lie inside the existing screen
  425. borders, everything will be fine.
  426.  
  427.   i denotes the number of the new image. If there is no existing sprite
  428. with this number, a new image will be created automatically. AMOS wlil
  429. also take the trouble of reserving the sprite bank if it hasn't been
  430. previously defined. See EXAMPLE 11.4
  431.  
  432.   There's also an equivalent GET BOB instruction which is identical to
  433. GET SPRITE in every respect. Since the sprite bank is shared by both
  434. bobs and sprites, the images are in exactly the same format. So it's
  435. perfectly acceptable to use both instructions in conjunction with
  436. either bobs or sprites. Try changing the sprite instruction in the
  437. previous example to something like:
  438.  
  439.         Bob 1,0,0,1
  440.  
  441.  
  442. Conversion functions
  443. ====================
  444.  
  445.  
  446.                  =X SCREEN (convert hardware coordinates 
  447.                  =Y SCREEN  into screen coordinates)
  448.  
  449. x=X SCREEN([n,] xcoord)
  450. y=Y SCREEN([n,] ycoord)
  451.  
  452. Transforms a hardware coordinate into a screen cordinate relative to
  453. the current screen. If the hardware coordinates lie outside the screen
  454. then both functions will return relative offsets from the screens
  455. boundaries. Type the following from direct mode:
  456.  
  457.         Print X Screen(130)
  458.  
  459. The result will be -2. This is because the x screen coordinate 0 is
  460. equal to hardware coordinate 128 and thus the conversion of 130 to a
  461. screen coordinate results in a position two pixels to the left of the
  462. screen.
  463.  
  464.   If the optional screen number is included then the coordinates will
  465. be returned relative to screen # n.
  466.  
  467.  
  468.  
  469.                   =X HARD (convert screen coordinates                      154
  470.                   =Y HARD  into hardware coordinates)
  471.  
  472. X=X HARD ([n,] xcoord)
  473.  
  474. These functions convert a screen coordinate into a hardware coordinate.
  475. There are four separate conversion functions, the above syntaz converts
  476. xcoord from a coordinate relative to the current screen to a hardware
  477. coordinate.
  478.  
  479. Y=Y HARD ([n,] ycoord)
  480.  
  481. Transforms a Y coordinate relative to the current screen into hardware
  482. coordinate. As before, n specififes a screen number for use with the
  483. functions. All coordinates will now be returned relative to this
  484. screen.
  485.  
  486.  
  487.  
  488.              =I SPRITE (return current image of a sprite)
  489.  
  490. Image=I SPRITE(n)
  491.  
  492. This function returns the current image number being used by sprite n.
  493. A value of zero will be reported if the sprite is not displayed.
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.                       12: BLITTER OBJECTS (BOBS)                           155
  503.                      ----------------------------
  504. While hardware sprites are certainly powerful, they do suffer from a 
  505. couple of annoying restrictions. The solution is to make use of the
  506. Amiga's infamous Blitter chip. This is capable of copying images to
  507. the screen at rates approaching a million pixels per second! With the
  508. help of the blitter it's possible to create what are known as bobs.
  509.  
  510.   Bobs, like sprites, can be moved around completely independently of
  511. the screen without destorying any existing graphics. But unlike
  512. sprites, bobs are sroted as part of the current screen, so you can
  513. create them in any graphics mode you wish. This allows you to generate
  514. bobs with up to 64 colours. Furthermore the only limit to the number 
  515. of bobs you can display is dictated by the available memory.
  516.  
  517.   Bobs are slightly slower than sprites and they consume considerably 
  518. more memory. Therefore there's a trade-off between the speed of sprites,
  519. and the flexibility of bobs. Fortunately there's nothing stopping you 
  520. from using both bobs and sprites in the same program.
  521.  
  522.  
  523.  
  524.                 BOB (draw a bob on the current screen)
  525.  
  526. BOB n,x,y,i
  527.  
  528. The BOB command creates bob n at coordinates x,y using the image # i.
  529.  
  530.   n is the identification number of the bob. Permissible values
  531. normally range from 0 to 63, but the number of bobs may be increased
  532. using an option from the AMOS configuration program. Providing you've
  533. enough memory, you can set this limit to any number you wish.
  534.  
  535.   x and y specify the position of the bob using standard screen
  536. coordinates. These coordinates are not the same as the hardware
  537. coordinates used by the equivalent SPRITE command. Like sprites, each
  538. bob is controlled through a *hot spot*. This may be changed at any time
  539. with the HOT SPOT command.
  540.  
  541.   i refers to an image which is to be assigned to the bob from the
  542. sprite bank. The format of this image is identical to that used by the
  543. sprites, so you can use the same images for either sprites or bobs.
  544.  
  545.   After you've created a bob, you can independently change either its
  546. position or its appearance by omitting one or more parameters from this
  547. instruction. Any of the numbers x,y or "image" may be left out, with
  548. the missing parameters retaining their original values. This is
  549. particularly useful if you are animating your bob with AMAL, as it
  550. allows you to move your object anywhere you like, without disturbing
  551. your existing animation sequence. However you must always include the
  552. commas in their original order. Example:
  553.  
  554.         Load "AMOS_DATA:Sprites/Octopus.abk"
  555.         Flash Off : Get Sprite Palette
  556.         Channel 1 To Bob 1
  557.         Bob 1,0,100,1
  558.         Amal 1,"Anim 0,(1,4)(2,4)(3,4)(4,4)"                               156
  559.         Amal On
  560.         For X=1 To 320
  561.           Bob 1,X,,
  562.           Wait Vbl
  563.         Next x
  564.  
  565. Whenever a bob is moved, the area underneath is replaced in its
  566. original position, producing an identical effect to the equivalent
  567. SPRITE command. Unlike STOS on the ST, each object is allocated its own
  568. individual storage area. This reduces the amount of memory used by
  569. bobs, and improves the overall performance dramatically. Due to the
  570. Blitter, of course, therse's no real comparison between STOS sprites
  571. and AMOS bobs.
  572.  
  573.   Although the BOB command works fine for small number of bobs, there's
  574. an annoying flicker when you try to use more than three or four objects
  575. on the screen at once. This happens because the bobs are updated at the
  576. same time as the screen. You can therefore see the bobs while they are
  577. being drawn which results in an unpleasant shimmering effect.
  578.  
  579.   One alternative for improving the quality of your animations is to
  580. just limit your bobs to the bottom quarter of the screen. Since bobs
  581. are redrawn extremely quickly, the updates can often be completed
  582. before the lower part of the screen has been displayed. This provides
  583. you with acceptably smooth movements while consuming very little
  584. memory, so it's a useful trick if you're running short of space. See
  585. EXAMPLE 12.1
  586.  
  587.   Obviously this cannot be seen as a serious solution to such a glaring
  588. problem. So before you throw away your copy of AMOS Basic in disgust,
  589. you'll be relieved to hear that there's a simple way of eliminating
  590. this flicker completely, even when you're using dozens of bobs anywhere
  591. on the screen:
  592.  
  593.  
  594.  
  595.              DOUBLE BUFFER (create a double screen buffer)
  596.  
  597. DOUBLE BUFFER
  598.  
  599. Creates a second invisible copy of the current screen. All graphics
  600. operations, including bob movements, are now performed directly in this
  601. *logical screen*, without disturbing your TV picture in the slightest.
  602. Once the image has been redrawn, the logical screen is displayed, and
  603. the original *physical* screen becomes the new logical screen. The
  604. entire process now cycles continuously, producing a rock solid display
  605. even when you're moving hundreds of bobs around the screen at once.
  606.  
  607.   The entire procedure is performed automatically by AMOS Basic, so
  608. after you've executed this instruction you can forget about it
  609. completely. Note that since the hardware sprites are always displayed
  610. using the current physical screen, this system will have absolutely no
  611. effect on any existing sprite animations.
  612.  
  613.   Double buffering works equally well in all of the AMIGA's graphics
  614. modes. It can even be used in conjuction with dual playfields. But be
  615. warned: Double buffering doubles the amount of memory used by your
  616. screens. If you attempt to double buffer too many screens, you'll
  617. quickly run out of memory. See EXAMPLE 12.2
  618.  
  619.   In practice, double buffering is an incredibly useful technique,
  620. which can be readily exploited for most types of games. It has seen
  621. service in the vast majority of commercial games, including Starglider
  622. - that's why it's such an integral part of AMOS Basic. A detailed
  623. explanation of this process can be found in the SCREENS chapter. ALso
  624. see the SCREEN SWAP and AUTOBACK commands.
  625.  
  626.  
  627.  
  628.                    SET BOB (set drawing mode of bob)                       157
  629.  
  630. SET BOB n,back,planes,minterms
  631.  
  632. The SET BOB command changes the drawing mode used to display a bob on
  633. the screen. n is the number of the bob you wish to affect.
  634.  
  635.   "back" chooses the way the background underneath your bob will be
  636. redrawn. There are three possibilities:
  637.  
  638.  - A value of 0 indicates that the area underneath your bob should be
  639.    saved in memory. The old image data is automatically replaced when
  640.    the bob is moved, resulting a smooth movement effect.
  641.  
  642.  - if the "back" parameter is positive then the original background
  643.    will be discarded altogether, and the area behind the bob will be
  644.    filled with colour "back"-1. This is ideal for moving bobs over a
  645.    solid block of colour such as a clear blue sky, as it's much faster
  646.    than the standard drawing system.
  647.  
  648.  - Turn of the redrawing process completely by loading "back" with a 
  649.    negative value such as -1. You can now deactivate the automatic
  650.    updating process using BOB UPDATE, and manually move your bobs with
  651.    a call to BOB DRAW. This allows you to regenerate the screen 
  652.    background using your own customised drawing routines.
  653.  
  654.   "planes" is a bit map which tells AMOS which screen planes your bob
  655. will be drawn in. As you may know, the Amiga's screen is divided up
  656. into a number of separate bit-planes. Each plane sets a single bit in
  657. the final colour which is displayed on the screen.
  658.  
  659.   The first plane is represnted by bit one, the second by bit two and
  660. so on. Normally the bob is drawn in all the bit-planes in the current
  661. screen mode. This corresponds to a bitpattern of %111111.
  662.  
  663.   By changing some of these bits to zero, you can omit selected colours
  664. from your bobs when they are drawn. This can be used to generate a
  665. number of intriguing screen effects.
  666.  
  667.   "minterms" selects the blitter mode used to draw your bobs on the
  668. screen. A full description of the available modes can be found in the
  669. section on SCREEN COPY. "minterm" is usually set to one of two values:
  670.  
  671.         %11100010   If the bob is used with a mask
  672.         %11001010   if NO MASK has been set
  673.  
  674. Feel free to experiment with the various combinations. There's no
  675. danger of crashing your Amiga if you make a mistake. Advanced Amiga
  676. users find the following information useful.
  677.  
  678.         Blitter source  Purpose                                            158
  679.         --------------  ------------------
  680.               A         Blitter mask
  681.               B         Blitter object
  682.               C         Destination screen
  683.  
  684. Note that you are recommended to use SET BOB *before* displaying your
  685. bobs on the screen. If you don't, the Amiga won't crahsh, and you won't
  686. get an error message, but your screen display may be corrputed.
  687.  
  688.  
  689.  
  690.                      NO MASK (remove blitter mask)
  691.  
  692. NO MASK [n]
  693.  
  694. As a default, a blitter mask is automatically created for every bob you
  695. display on the screen. This mask is combined with the screen background
  696. to make colour zero transparent. It's also used by the various
  697. collision detection commands.
  698.  
  699.   The NO MASK command removes this mask, and forces the entire image to
  700. be drawn on the screen. Any parts of the image in colour zero will now
  701. be displayed directly over the existing background.
  702.  
  703.   n is the image number whose mask is to be removed. This mask should
  704. never be erased if the image is active on the screen, otherwise the
  705. sasociated bob will be corrupted. If you must remove the mask in this
  706. way, it's important to deactivate the relevant bobs with BOB OFF first.
  707. Here's an example:
  708.  
  709.         Centre "Click mouse button to remove mask"
  710.         Double buffer : Load "AMOS_DATA:Sprites/Octopus.abk"
  711.         Get Sprite Palette
  712.         Do
  713.           Bob 1,X Screen(X Mouse),Y Screen(Y Mouse),1
  714.           If Mouse Click Then Bob Off : No Mask 1
  715.         Loop
  716.  
  717. See MAKE MASK
  718.  
  719.  
  720.                         AUTOBACK (set automatic
  721.                          screen copying mode)
  722.  
  723. AUTOBACK n
  724.  
  725. When you are using a double bufferend screen, it's essential to
  726. synchronize your drawing operations with the movements of your blitter
  727. objects. Remember that each double buffered screen consists of two
  728. separate displays. There's one screen for the current picture, and
  729. another for the image whilst it's being constructed. If the background
  730. underneath a bob changes while it's being redrawn, the contents of
  731. these screens will be different, and you'll get an intense and annoying
  732. flickering efect.
  733.  
  734.   The unique AMOS AUTOBACK system provides you with a perfect solution
  735. to this problem. It allows you to generate your graphics in any one of
  736. three graphics modes, depending on the precise requirements of your
  737. program. Just for a change, we'll list tese options in reverse order.
  738.  
  739.  
  740. AUTOBACK 2 (automatic mode - default)                                      159
  741.  
  742.   In this mode, all drawing operations are automatically combined with 
  743.   the bob updates. So anything you draw on the screen will be displayed 
  744.   directly underneath your bobs, as if by magic. The principles behing
  745.   this system can be demonstrated by the following code:
  746.  
  747.         Bob Clear : Rem    Draw on first screen ... Remove Bobs
  748.         Plot 150,100 : Rem This can be anything you wish
  749.         Bob Draw : Rem     Redraw bobs
  750.         Screen Swap : Rem  Next Screen
  751.         Wait Vbl
  752.         Bob Clear
  753.         Plot 150,100 : Rem Perform your operation a second time
  754.         Bob Draw
  755.         Screen Swap : Rem  Get back to first screen
  756.         Wait Vbl
  757.  
  758.   As you can see, all screen updates are performed exactly twice.
  759.   There's one operation for both the logical and the physical screen.
  760.   See EXAMPLE 12.3 for a demonstration.
  761.  
  762.     One obvious side effect, is that your graphics now take twice as 
  763.   long to be drawn. Furthermore, the program will be halted by at least
  764.   2 vertical blanks, every time you output something to the screen. 
  765.   This may cause annoying delays in the execution of critical
  766.   activities such as collision detection.
  767.  
  768.  
  769. AUTOBACK 1 (half-automatic mode)
  770.  
  771.   Performs each graphical operation in both the physical and logical
  772.   screens. Absolutely no account is taken of your bobs, so you should
  773.   only use this system for drawing outside the current playing area.
  774.  
  775.     Unlike the standard mode, there's no need to halt your program
  776.   until the next vertical blank. Mode 1 is therefore ideal for objects
  777.   such as control panels or hi-score tables, which need to be updated
  778.   continually during the game.
  779.  
  780.  
  781. AUTOBACK 0 (manual mode)
  782.  
  783.   Stops the AUTOBACK system in it's tracks. All graphics are now output
  784.   straight to the logical screen at the maximum possible speed. You
  785.   should use this option if you need to repeatedly redraw large
  786.   sections of your background screen during the course of a game. 
  787.   This will allow you to safely perform your collision detection 
  788.   routines at regural intervals, without destroying the overall quality
  789.   of the animation effects. Here's a typical program loop for you to
  790.   examine.
  791.  
  792.         Bob Update Off
  793.         Repeat
  794.         Screen Swap
  795.         Wait Vbl
  796.         Bob Clear
  797.         Rem Now redraw any of your gfxs which have changed                 160
  798.         Rem Perform your game routines (Collision detection etc...)
  799.         Bob draw
  800.         Until WIN
  801.  
  802. Note that this procedure will ONLY work if there's a smooth progression
  803. from screen to screen. It's entirely up to you to keep the contents of
  804. physical and logical screen in step with each other. An example of this
  805. technique can be found in EXAMPLE 12.4
  806.  
  807.   Supposing for instance, you wanted to display a bob over a series of
  808. random blocks. You might try to use a routine like:
  809.  
  810.         Load "AMOS_DATA:Sprites/Sprites.abk" : Flash Off 
  811.         Get Sprite Palette : Double Buffer : Cls 0 : Autoback 0
  812.         Update Off : Bob 1,160,100,1
  813.         Do
  814.           Bob Clear
  815.           X=Rnd(320)+1 : Y=Rnd(200)+1 : W=Rnd(80)+1
  816.           H=Rnd(50)+1 : I=Rnd(15)
  817.           Ink I : Bar X,Y To X+W,Y+H
  818.           Rem <this would normally call your collision detection routine>
  819.           Bob Draw
  820.           Screen swap : Wait Vbl
  821.         Loop
  822.  
  823. But since there's no relationship between the physical and logical
  824. screens, the display will now flick continuously from screen to screen.
  825. To overcome this problem, you'll need to mimic the original AUTOBACK
  826. system. Replace the lines in the previous example between the lines
  827. Do and Loop  as follows:
  828.  
  829.           Rem Update first screen
  830.           Screen Swap : Wait Vbl
  831.           Bob Clear
  832.           X=Rnd(320)+1 : Y=Rnd(200)+1 : W=Rnd(80)+1
  833.           H=Rnd(50)+1 : I=Rnd(15)
  834.           Ink I : Bar X,Y To X+W,Y+H
  835.           Bob Draw
  836.           Rem Update second screen
  837.           Screen Swap : Wait Vbl
  838.           Bob Clear
  839.           Ink I : Bar X,Y To X+W,Y+H
  840.           Bob Draw
  841.  
  842. The two screens are now updated with exactly the same information, and     161
  843. the display remains as steady as a rock, even though there's a great
  844. deal of activity going on in the background.
  845.  
  846.   Autoback can be safely used at any point in your program. So it's
  847. perfectly possible to use separate drawing methods for the different
  848. parts of your screen. It's also totally compatible with all graphics
  849. operations including Blocks, Icons, and Windowing.
  850.  
  851.  
  852. Bob Control commands
  853. ====================
  854.  
  855.  
  856.                    BOB UPDATE (control bob movements
  857.  
  858. BOB UPDATE [ON/OFF]
  859.  
  860. Normally all bobs are updated once every 50th of a second using a
  861. built-int interrupt routine. Alhouth this is convenient for most
  862. programs, there are some applications which require much finer control
  863. over the redrawing process.
  864.  
  865.   BOB UPDATE OFF turns off the bob updates and deactivates all
  866. automatic screen switching operations if they've been selected. You may
  867. now redraw your bobs at the most appropriate point in your program
  868. using the BOB UPDATE command. This is ideal when you are animating a
  869. large number of objects as it enables you to move your bobs into
  870. position before drawing them on the screen. Inevitably this results in
  871. far smoother movements in your game.
  872.  
  873.   One word of warning: The bob updates will only occur at the NEXT
  874. vertical blank. Also note that BOB UPDATE will always redraw the bobs
  875. on the current logical screen, so if you forget to use the SCREEN SWAP
  876. command, nothing will apparently happen.
  877.  
  878.  
  879.  
  880.             BOB CLEAR (remove all the bobs from the screen)
  881.  
  882. BOB CLEAR
  883.  
  884. Removes all active bobs from the screen, and redraws the background
  885. regions underneath. It's inteded for use with BOB DRAW to provide an
  886. alternative to the standard BOB UPDATE command
  887.  
  888.  
  889.  
  890.                         BOB DRAW (redraw bobs)
  891.  
  892. BOB DRAW
  893.  
  894. Whenever the bobs are redrawn on the screen, the following steps are
  895. automatically performed:
  896.  
  897.  1. All active bobs are removed from the LOGICAL screen and the
  898.     background regions are replaced. This step is performed by BOB
  899.     CLEAR.
  900.  2. A list is made of all bobs which have moved since the previous
  901.     update.
  902.  3. The background regions under the new screen coordinates are saved
  903.     in memory.
  904.  4. All active bobs are redrawn at their new positions on the logical      162
  905.     screen
  906.  5. If the DOUBLE BUFFER feature has been activated, the physical
  907.     and logical screens are now swapped
  908.  
  909. The BOB DRAW command performs steps 2 to 4 of this process directly.
  910. Supposing you wished to create a screen scrolling arcade game. In this
  911. situation, it would be absolutely vital for your scrolling operations
  912. to be perfectly synchronized with movement effects. If the aliens were
  913. to move while the scrolling was taking place, their background areas
  914. would be redrawn at the wrong place. This would totally corrupt your
  915. display, and would result in a hopeless jumble on the screen. Load
  916. EXAMPLE 12.5 for a demonstration of this process.
  917.  
  918.  
  919.  
  920.                    =X BOB (get X coordinate of bob)
  921.  
  922. x1=X BOB(n)
  923.  
  924. Returns the current X coordinate of bob number n. This coordinate is
  925. measured relative to the current screen. See also Y SPRITE, X MOUSE and
  926. Y MOUSE.
  927.  
  928.  
  929.  
  930.                    =Y BOB (get Y coordinate of bob)
  931.  
  932. y1=Y BOB(n)
  933.  
  934. Y BOB complements the X BOB command by returning the Y coordinate of
  935. bob number n. This value will be returned using normal screen
  936. coordinates.
  937.  
  938.  
  939.  
  940.                  =I BOB (return current image of bob)
  941.  
  942. Image=U BOB(n)
  943.  
  944. This function returns the current image number being used by bob n. A
  945. value of zero will be reported if the bob isn't displayed.
  946.  
  947.  
  948.  
  949.                 LIMIT BOB (limit a bob to a rectangular
  950.                          region of the screen)
  951.  
  952. LIMIT BOB [n,] x1,y1 TO x2,y2
  953.  
  954. This command restricts the visibility of your bobs to a rectangular
  955. screen area enclosed by the coordinates x1,y1 to x2,y2. The x
  956. coordinates are rounded up to the nearest 16-pixel boundary. Note that
  957. the width of this region must always be greater than the width of your
  958. bobs, otherwise you'll get an "illegal function call" error.
  959.  
  960.   If it's included, n specifies the number of a single bob which is to
  961. be affected by this instruction, otherwise *all* bobs will be
  962. restricted. You can restore the visibility limit to the entire entire
  963. screen by typing:
  964.  
  965.         LIMIT BOB
  966.  
  967.  
  968.  
  969.                  GET BOB (load a section of the screen                     163
  970.                          into the sprite bank)
  971.  
  972. GET BOB [s,] i,x1,y1 TO x2,y2
  973.  
  974. This instruction is identical to the GET SPRITE command. It grabs an
  975. image into the sprite bank from the current screen.
  976.  
  977.   x1,y1 to x2,y2 are the coordinates of the top and bottom corners of
  978. the rectangular area to be grabbed.
  979.  
  980.   i specifies the image number which is to be loaded with this area. s
  981. selects an optional screen number from which the image is to be taken.
  982. See GET SPRITE for more details. See also EXAMPLE 12.6.
  983.  
  984.  
  985.  
  986.              PUT BOB (fix a xopy of a bob onto the screen)
  987.  
  988. PUT BOB n
  989.  
  990. This is the exact opposite of the previous GET BOB command. The action
  991. of PUT BOB is to place a copy of bob number n at its present position
  992. on the screen. It works by preventing the background underneath the bob
  993. from being redrawn during the next vertical blank period. In order to
  994. synchronise the bob updates with the screen display, you should always
  995. follow this command with a WAIT VBL instruction.
  996.  
  997.   Note that after this instruction has been performed, the original bob
  998. may be moved or animated with no ill efects.
  999.  
  1000.  
  1001.  
  1002.                PASTE BOB (draw an image from the sprite 
  1003.                           bank on the screen)
  1004.  
  1005. PASTE BOB x,y,i
  1006.  
  1007. The PASTE BOB command draws a copy of image number i at *screen*
  1008. coordinates x,y. Unlike PUT BOB this image is drawn on the screen
  1009. immediately, and all the normal clipping rules are obeyed. See PASTE
  1010. ICON.
  1011.  
  1012.  
  1013.                 BOB OFF (remove a bob from the display)
  1014.  
  1015. BOB OFF [n]
  1016.  
  1017. Occasinoally, you may wish to remove certain bobs from the screen
  1018. altogether. The BOB OFF command erases bob number n from the screen and
  1019. terminates any associated animations. If n is omitted, all bobs will be    164
  1020. removed by this instruction.
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.                           13: OBJECT CONTROL                               165
  1027.                       ---------------------------
  1028. In this section you will find out how the various objects generated
  1029. using the sprite and bob commands can be controlled from within an AMOS
  1030. Basic program. The topics under discussion include collision detection,
  1031. using the mouse cursor and reading the joystick.
  1032.  
  1033.  
  1034. The mouse pointer
  1035. =================
  1036. The mouse cursor provides the games programmer with a valuable
  1037. alternative to the standard joystick. With the CHANGE MOUSE command you
  1038. can replace the mouse with an image in the current sprite bank. There's
  1039. also a group of instructions which allow you to determine both the
  1040. position and status of this mouse at any time. These include the  
  1041. X MOUSE, Y MOUSE and MOUSE KEY instructions.
  1042.  
  1043.  
  1044.  
  1045.               HIDE (remove mouse pointer from the screen)
  1046.  
  1047. HIDE [ON]
  1048.  
  1049. This command removes the mouse pointer from the screen completely. A
  1050. count of the number of occasions you have called this function is kept
  1051. internally by the system. This needs to be matched by an equal number
  1052. of SHOW instructions before the pointer will be returned on the screen.
  1053.  
  1054.   There's also another version of this instruction which can be
  1055. accessed with HIDE ON. This ignores the count and *always* hides the
  1056. mouse, no matter how many times you've called the SHOW command.
  1057.  
  1058.   Note that HIDE only makes the mouse pointer invisible. It has no
  1059. effect on any other AMOS commands, so you can still use X MOUSE and
  1060. Y MOUSE functions to read the coordinates of the mouse as normal.
  1061.  
  1062.  
  1063.  
  1064.                    SHOW (activate the mouse pointer)
  1065.  
  1066. SHOW [ON]
  1067.  
  1068. This returns the mouse pointer to the screen after a HIDE instruction.
  1069. Works the same way that HIDE does.
  1070.  
  1071.  
  1072.  
  1073.                    CHANGE MOUSE (change the shape of
  1074.                           the mouse pointer)
  1075.  
  1076. CHANGE MOUSE m
  1077.  
  1078. This allows you to change the shape of the mouse at any time. Three
  1079. mouse patterns are provided as standard. These can be assigned using
  1080. the numbers 1-3.
  1081.  
  1082. If you specify a value m greater than 3, this is assumed to refer to an    166
  1083. image stored in the sprite bank. The number of this image is determined
  1084. using the expression I=m-3. So image number 1 would be installed by a
  1085. value of 4.
  1086.  
  1087.   In order to use this option, your sprite image must be exactly 16
  1088. pixels wide and have no more than four colours. However there's no such
  1089. limit to the height of your image. 
  1090.  
  1091.  
  1092.  
  1093.                =MOUSE KEY (read status of mouse buttons)
  1094.  
  1095. k=MOUSE KEY
  1096.  
  1097. Enables you to quickly check whether one or more of the mouse keys have
  1098. been pressed. It returns a bit-pattern which holds the current status
  1099. of the mouse buttons.
  1100.  
  1101.         Bit 0   Set to 1 if the LEFT   button pressed, otherwise zero.
  1102.         Bit 1   Set to 1 if the RIGHT  button pressed, otherwise zero.
  1103.         Bit 2   Set to 1 if the MIDDLE button pressed (if available).
  1104.  
  1105.  
  1106.  
  1107.                 =MOUSE CLICK (check for a mouse click)
  1108.  
  1109. c=MOUSE CLICK
  1110.  
  1111. Checks wheter the user has "clicked" on a mouse button. Uses the same
  1112. bit pattern indication as =MOUSE KEY.
  1113.  
  1114. One shot tests are only set to 1 when the mouse key has just been
  1115. pressed. These bits are automatically reset to zero after they've been
  1116. tested once. So they will only check for a single key press at a time.
  1117.  
  1118.  
  1119.  
  1120.        =XMOUSE= (get/set the X coordinate of the mouse pointer)            167
  1121.  
  1122. x1=X MOUSE
  1123.  
  1124. X MOUSE returns the current X coordinate of the mouse pointer in
  1125. hardware notation. You can also use this function to move the mouse on
  1126. to a specific screen position. This can be achieved by assigning X
  1127. MOUSE with a value, just like a Basic variable, for example:
  1128.  
  1129.         X MOUSE=150
  1130.  
  1131.  
  1132.  
  1133.        =YMOUSE= (get/set the Y coordinate of the mouse pointer)
  1134.  
  1135. y1=Y MOUSE
  1136.  
  1137. Returns the Y coordinate of the mouse pointer. This can also be used to
  1138. set the Y position of the mouse pointer the same way as using X MOUSE.
  1139. See EXAMPLE 13.1 for an example of the X MOUSE and Y MOUSE.
  1140.  
  1141.  
  1142.  
  1143.                  LIMIT MOUSE (limit mouse to a section
  1144.                             of the screen)
  1145.  
  1146. LIMIT MOUSE x1,y1 TO x2,y2
  1147.  
  1148. Restricts mouse movements to the rectangular area defined by the
  1149. hardware coordinates (x1,y1) and (x2,y2). Note that unlike LIMIT BOB,
  1150. the mouse is completely trapped inside this zone and cannot be moved
  1151. beyond it. Simply use this instruction with no parameters to restore
  1152. the mouse to the full screen area.
  1153.  
  1154.         LIMIT MOUSE
  1155.  
  1156. See also EXAMPLE 13.2 from the manual folder for a demonstration.
  1157.  
  1158.  
  1159. Reading the joystick
  1160. ====================
  1161. AMOS Basic includes six functions which allow you to immediately check
  1162. the movements of a joystick insterted in either of the available
  1163. sockets.
  1164.  
  1165.  
  1166.  
  1167.                          =JOY (read joystick)                              168
  1168.  
  1169. d=JOY(j)
  1170.  
  1171. This function returns a binary number which represnts the current
  1172. status of a joystick in port number j. Normally your joystick will be
  1173. placed in the left socket (number 1). However you can remove the mouse
  1174. from the right-hand socket and replace it with a joystick. This can be
  1175. accessed using port # 0.
  1176.  
  1177.   The state of the joystick can be read by inspecting the pattern of
  1178. binary bits in the result. Each bit indicates whether a specific action
  1179. has been performed by the user. If a bit is set to one then the test
  1180. has proved positive and the joystick has been moved in the appropriate
  1181. direction. Here's a list of the various bits and their meanings:
  1182.  
  1183.         Bit Number   Significance
  1184.         ----------   ------------
  1185.             0        Joy moved up
  1186.             1            "     down
  1187.             2            "     left
  1188.             3            "     right
  1189.             4        Fire button pressed
  1190.  
  1191. See EXAMPLE 13.3
  1192.  
  1193. You can also use the following commands, if you are not familiar with
  1194. this binary notation:
  1195.  
  1196.  
  1197.  
  1198.                 =JLEFT(j) (test joystick movement left)
  1199.                =JRIGHT(j) (test joystick movement right)
  1200.                   =JUP(j) (test joystick movement up)
  1201.                 =JDOWN(j) (test joystick movement down)                    169
  1202.  
  1203. x=JLEFT(j)
  1204. x=JRIGHT(j)    These functions return a value of -1(true) if the 
  1205. x=JUP(j)       joystick in port j has been pulled to the associated
  1206. x=JDOWN(j)     direction. Value 0 is reported, if the condition is
  1207.                false (joystick hasn't been moved to the asked
  1208.                direction).
  1209.  
  1210.  
  1211. Detecting collisions
  1212. ====================
  1213. If you're writing an arcade game it's vital to be able to accurately
  1214. check for collisions between the various objects on the screen. AMOS
  1215. Basic includes five powerful functions which allow you to perform these
  1216. tests quickly and easily.
  1217.  
  1218.  
  1219. Detecting collisions with a sprite
  1220. ----------------------------------
  1221.  
  1222.  
  1223.                  SPRITE COL (detect collisions between
  1224.                          two hardware sprites)
  1225.  
  1226. c=SPRITE COL (n [,s TO e])
  1227.  
  1228. This provides you with a simple way of testing to see whether two or
  1229. more sprites have collided on the screen. The number n refers to an
  1230. active hardware sprite which is to be clicked for a collision. If a
  1231. collision has occurred a value of -1(true) will be returned, otherwise
  1232. the result will be set to 0 (false).
  1233.  
  1234.   The standard from of this function checks for all collisions. But you
  1235. can also test a whole group of sprites using an extended version of the
  1236. command:
  1237.  
  1238.         c=SPRITE COL n,s TO e
  1239.  
  1240. The above instruction checks for collisions between sprite n and
  1241. sprites s to e (inclusive). Once you've detected a collision, you can
  1242. then get the individual sprite numbers which have vollided using the
  1243. COL function.
  1244.  
  1245.   NOTE that in order to use this function, you'll need to create a
  1246. sprite mask with the MASK command first, otherwise your collisions will
  1247. not be detected. A detailed example of this command can be found in
  1248. EXAMPLE 13.4.
  1249.  
  1250.  
  1251. Detecting collisions with a bob                                            170
  1252. -------------------------------
  1253.  
  1254.  
  1255.                   BOB COL (detect collisions between
  1256.                          two blitter objects)
  1257.  
  1258. c=BOB(n, [,s TO e])
  1259.  
  1260. The BOB COL function checks bob number n for a collision with another
  1261. bob. If a collision has been detected, the value returned in c will be
  1262. set to -1 (true), otherwise it will be 0.
  1263.  
  1264.   Normally the command will check for all collisions, but you can
  1265. specify a collection of bobs to be tested using the optional range
  1266. parameters s to e. The status of these bobs can be individually
  1267. examined with the COL command. See EXAMPLE 13.5.
  1268.  
  1269.  
  1270. Collisions between bobs and sprites
  1271. -----------------------------------
  1272.  
  1273.  
  1274.               SPRITEBOB COL (test for a collision between
  1275.                            sprites and bobs)
  1276.  
  1277. c=SPRITEBOB COL(n [,s TO e])
  1278.  
  1279. This function checks for a collision between SPRITE n ane one or more
  1280. BOBS. The value of c will be either -1 if a collision has been
  1281. discovered, or 0 if there have been no collisions. The starting and
  1282. ending points specify that collisions will only be detected between the
  1283. bobs s to e. If they are not included then all active bobs will be
  1284. tested by this instruction.
  1285.  
  1286.   WARNING! Collision detection between a sprite and a bob is only
  1287. possible on a low resolution screen. In HiRes mode, the pixel sizes
  1288. used for bobs and sprites are totally different, and the results from
  1289. this function will be unreliable.
  1290.  
  1291.  
  1292.  
  1293.               BOBSPRITE COL (test for a collision between
  1294.                            bobs and sprites)
  1295.  
  1296. c=BOBSPRITE COL(n, [,s TO e])
  1297.  
  1298. The BOB SPRITE COL function checks for collisions between a single bob
  1299. and several sprites. The results and usage of this instruction are 
  1300. same as in the SPRITEBOB COL. See EXAMPLE 13.6.
  1301.  
  1302.  
  1303.  
  1304.                  =COL (test the status of a sprite or
  1305.               bob after a collision detection intruction)
  1306.  
  1307. c=COL(n)
  1308.  
  1309. The COL array holds the status of all the objects which have been
  1310. previously tested by the collision detection functions.
  1311.  
  1312.   Each object you have checked is associated with one element in this
  1313. array. This element will be loaded with -1 if a collision has been
  1314. detected with object number n, or 0 if it has not. The numbering system
  1315. is simple: The first element in the array holds the status of object
  1316. number 1, the second represents object number 2, and so on. See EXAMPLE
  1317. 13.7.
  1318.  
  1319.   If you are using the SPRITE COL or BOBSPRITE COL instructions then
  1320. the objects will be hardware sprites, otherwise they will be bobs. In
  1321. order to avoid confusion, it's sensible to call this instructoin
  1322. immediatly after the relevant detection command.
  1323.  
  1324.  
  1325.  
  1326.                 HOT SPOT (set the hot spot for an image                    171
  1327.                           in the sprite bank)
  1328.  
  1329. HOT SPOT image,x,y
  1330. HOT SPOT image,p
  1331.  
  1332. This command sets the hot spot of an image stored in the current sprite
  1333. bank. The hot spot of the object is used as a reference point for all
  1334. coordinate calculations. There are two versions of this instruction.
  1335.  
  1336.         HOT SPOT image,x,y
  1337.  
  1338. x and y coordinates measured from the top left corner of the image.
  1339. These coordinates will be added to the sprite bank or bob coordinate to
  1340. position an object precisely on the screen.
  1341.  
  1342.               Sprite image
  1343.               +----------+        Note that it's perfectly
  1344.               :          :        lefal for the hot spot
  1345.               : x        :        to lie outside the 
  1346.               :<-->*     :        actual image.
  1347.               :  hot spot:
  1348.               +----------+
  1349.  
  1350.         HOT SPOT image,p
  1351.  
  1352. This is a short form of the instruction which moves the hot spot to one
  1353. of nine predefined positions. The positions are shown in the diagram
  1354. below where the centre point of the image is represent by a value of       172
  1355. $11.
  1356.  
  1357.         $00     $10     $20
  1358.         $01     $11     $21        See EXAMPLE 13.8.
  1359.         $02     $12     $22
  1360.  
  1361.  
  1362.  
  1363.                         MAKE MASK (make a mask
  1364.                around an image for collision detection)
  1365.  
  1366. MAKE MASK [n]
  1367.  
  1368. Defines a mask around image number n in the sprite bank. This is used
  1369. by all the AMOS Basic collision detection commands. You should
  1370. therefore create a mask for every object you wish to check. If you omit
  1371. the image number n, then a mask will be generated for each image in the
  1372. sprite bank. This may take a little time.
  1373.  
  1374.   It's important to note that masks are generated automatically when a
  1375. bob is first drawn on the screen. This might cause a significant delay
  1376. in the running of your program, so it's worthwhile placing an explicit
  1377. call to MAKE MASK during your initialisation procedure.
  1378.  
  1379.  
  1380. Collisions with rectangular blocks
  1381. ----------------------------------
  1382. AMOS Basic includes a number of functions which allow you to quickly
  1383. check whether a sprite or bob has entered a rectangular region of the
  1384. screen.
  1385.  
  1386.   These screen zones are especially useful for collision detection in
  1387. rebound games such as Arkanoid as each block can be assignet its own
  1388. individual screen zone. You can also use zones to construct the buttons
  1389. and switches needed for control panels and dialogue boxes.
  1390.  
  1391.  
  1392.  
  1393.            RESERVE ZONE (reserve space for a detection zone)
  1394.  
  1395. RESERVE ZONE [n]
  1396.  
  1397. RESERVE ZONE allocates enough memory for exactly n detection zones.
  1398. This command should always be used before defining a zone with SET
  1399. ZONE.
  1400.  
  1401.   The only limit to the number of zones is the amount of available
  1402. memory, so it's perfectly feasible to define hundreds or even thousands
  1403. of zones in one of your programs. To erase the current zone definitions
  1404. and restore the memory back to the main program, simply type 
  1405.  
  1406.         RESERVE ZONE    with no parameters.
  1407.  
  1408.  
  1409.  
  1410.                    SET ZONE (set a zone for testing)
  1411.  
  1412. SET ZONE z,x1,y1 TO x2,y2
  1413.  
  1414. Defines a rectangular zone which can be subsequently tested using the
  1415. various ZONE commands. z specifies the number of the zone to be created
  1416. and x1,y1 and x2,y2 input the coordinates of the top left and bottom
  1417. right hand corners of the rectangle.
  1418.  
  1419.   Before using this instruction you'll need to reserve some space for
  1420. your zones with RESERVE ZONE.
  1421.  
  1422.  
  1423.  
  1424.                    =ZONE (return the zone under the                        173
  1425.                    the requested screen coordinates)
  1426.  
  1427. t=ZONE([s],x,y)
  1428.  
  1429. ZONE returns the number of the screen zone at the graphic coordinates
  1430. x,y. Normally the coordinates are relative to the current screen - you
  1431. can also include an optional screen number s in this function.
  1432.  
  1433.   After ZONE has been called, t will hold either the number of the zone
  1434. at the specified coordinates or a value of 0 (false).
  1435.  
  1436.   Note that ZONE only returns the first zone at these coordinates - it
  1437. won't detect any other zones which lie inside this region. 
  1438.  
  1439.   It is possible to use this function in conjunction with X BOB and
  1440. Y BOB functions to detect whether a bob has entered a specific screen
  1441. zone. This can be accomplished using the following code:
  1442.  
  1443.         X=Zone(X bob(n),Y Bob(n))
  1444.  
  1445. See Examples 13.9 and 13.10.
  1446.  
  1447.  
  1448.  
  1449.                    =HZONE (return the zone under the
  1450.                     requested hardware coordinates)
  1451.  
  1452. t=HZONE([s],x,y)
  1453.  
  1454. HZONE is almost identical to ZONE except that the screen position is
  1455. now measured in hardware coordinates. You can therefore use this
  1456. function to detect when a hardware sprite enters one of your screen
  1457. zones. For example:
  1458.  
  1459.         X=Hzone(X Sprite(n),Y Sprite(n))
  1460.  
  1461. See also EXAMPLE 13.11, and ZONE, MOUSE ZONE, SET ZONE and ZONE$
  1462.  
  1463.  
  1464.  
  1465.               =MOUSE ZONE (check wheter the mouse pointer
  1466.                           has entered a zone)
  1467.  
  1468. x=MOUSE ZONE
  1469.  
  1470. The MOUSE ZONE function returns the number of the screen zone currently
  1471. occupied by the mouse pointer. It's equibalent to the line:
  1472.  
  1473.         X=Hzone(X mouse,Y mouse)
  1474.  
  1475.  
  1476.  
  1477.                        RESET ZONE (erase a zone)                           174
  1478.  
  1479. RESET ZONE [z]
  1480.  
  1481. This command permanently deactivats any of the zones created by SET
  1482. ZONE. If the optional zone number z is included then only this zone
  1483. will be reset, otherwise all the zones will be affected. Note that
  1484. RESET ZONE only erases the zone definitions, it does not return the
  1485. memory allocated by RESERVE ZONE.
  1486.  
  1487.  
  1488. Bob priority
  1489. ============
  1490.  
  1491.  
  1492.             PRIORITY ON/OFF (change between priority modes)
  1493.  
  1494. PRIORITY ON/OFF
  1495.  
  1496. Each bob is assigned a priority value ranging from 0-63. Amos basic
  1497. uses this number to decide which order the objects should be displayed
  1498. on the screen. As a rule, any bob with the highest priority will always
  1499. be displayed in front if any objects with a lower priority. The
  1500. priority value is taken directly from the number of a Bob.
  1501.  
  1502.   You should remember this fact when assigning numbers to your bobs.
  1503. The choise of number can have wide ranging effects on the appearance of
  1504. your objects on the screen.
  1505.  
  1506.   In addition to the standard system, it's also possible to arrange the
  1507. bobs according to their position on the screen. PRIORITY ON assigns the
  1508. greatest priority values to the bobs with the highest Y coordinates.
  1509. This allows you to create a useful illusion of perspective in your
  1510. games. Look at the example below:
  1511.  
  1512.         Load "AMOS_DATA/Sprites/Monkey_right.abk" : Cls : Flash Off
  1513.         Get Sprite Palette
  1514.         Priority Off : Rem Set normal mode
  1515.         Bob 1,160,100,2 : Bob 2,0,72,2 : Bob 3,320,128,2
  1516.         Channel 2 To Bob 2 : Channel 3 to Bob 3
  1517.         Amal 2," Loop: M 320,0,320 ; M -320,0,320 ; Jump Loop"
  1518.         Amal 3," Loop: M -320,0,320 ; M 320,0,320 ; Jump Loop"
  1519.         Amal On
  1520.         Wait Key
  1521.         Priority On : Rem Set Y mode
  1522.         Wait Key
  1523.  
  1524. Normally, both moving bobs pass below the object in the centre. When
  1525. you change the priority system with a call to PRIORITY ON, the bobs are
  1526. now ranked in order of their increasing Y coordinates. So bob three
  1527. moves aboce bob one while at the same time, bob two passes smoothly
  1528. behind it.
  1529.  
  1530.   HINT: It's usually best to position the Hot Spot of the sprite at its
  1531. base. This is because the Y coordinates used by this command relate to
  1532. the position of the Hot Spot on the screen. Also notice that the
  1533. PRIORITY OFF instruction can be utilised to reset the priority back to
  1534. normal.
  1535.  
  1536.  
  1537. Miscellaneous commands                                                     175
  1538. ======================
  1539.  
  1540.  
  1541.              UPDATE (change automatic sprite/bob updates)
  1542.  
  1543. UPDATE [ON/OFF]
  1544.  
  1545. Normally any objects you draw on the screen will be automatically
  1546. redisplayed whenever they are animated or moved. This feature can be
  1547. temporarily halted using the UPDATE OFF command. When the updates are
  1548. not active the SPRITE, BOB and AMAL commands apparently have no effect.
  1549. Actually, all your animations are working correctly - it's just that
  1550. the results are not being displayed on the screen. You can force this
  1551. redrawing operation at any time using the UPDATE command. Here are the
  1552. three different forms of the UPDATE instruction.
  1553.  
  1554.         UPDATE OFF
  1555.  
  1556. Turns of the automatic updating.
  1557.  
  1558.         UPDATE
  1559.  
  1560. Redraws any sprites which have changed their original positions
  1561.  
  1562.         UPDATE ON
  1563.  
  1564. Returns the sprite updating to normal. See EXAMPLE 13.12.
  1565.